
const { JSDOM } = require('jsdom');
const querystring = require('querystring');
const sealedbox = require('tweetnacl-sealedbox-js');
const naclUtil = require('tweetnacl-util');

function encPassword(password, key_id, public_key, version) {

    var h, i = globalThis.crypto,
        j = 64,
        k = 1,
        l = 1,
        m = 1,
        n = 2,
        o = 32,
        p = 16,
        q = l + m + n + o + sealedbox.overheadLength + p;
    function r(a, b) {
        return sealedbox.seal(a, b)
    }
    function s(a) {
        var b = [];
        for (var c = 0; c < a.length; c += 2)
            b.push(parseInt(a.slice(c, c + 2), 16));
        return new Uint8Array(b)
    }
    function a(a, d, e, f) {
        var g = q + e.length;
        if (d.length != j)
            throw new Error("public key is not a valid hex sting");
        var t = s(d);
        if (!t)
            throw new Error("public key is not a valid hex string");
        var u = new Uint8Array(g)
            , v = 0;
        u[v] = k;
        v += l;
        u[v] = a;
        v += m;
        d = {
            name: "AES-GCM",
            length: o * 8
        };
        var w = {
            name: "AES-GCM",
            iv: new Uint8Array(12),
            additionalData: f,
            tagLen: p
        };
        return i.subtle.generateKey(d, !0, ["encrypt", "decrypt"]).then(function (a) {
            var c = i.subtle.exportKey("raw", a);
            a = i.subtle.encrypt(w, a, e.buffer);
            return Promise.all([c, a])
        }).then(function (a) {
            var b = new Uint8Array(a[0]);
            b = r(b, t);
            u[v] = b.length & 255;
            u[v + 1] = b.length >> 8 & 255;
            v += n;
            u.set(b, v);
            v += o;
            v += sealedbox.overheadLength;
            if (b.length !== o + sealedbox.overheadLength)
                throw new Error("encrypted key is the wrong length");
            b = new Uint8Array(a[1]);
            a = b.slice(-p);
            b = b.slice(0, -p);
            u.set(a, v);
            v += p;
            u.set(b, v);
            return u
        })
    }

    const as = key_id
    const bs = public_key
    const es = naclUtil.decodeUTF8(password);
    const randomTime = Math.trunc(Date.now() / 1000).toString()
    const ks = naclUtil.decodeUTF8(randomTime);

    const ps = a(as, bs, es, ks).then((res) => {
        let j = '#PWD_INSTAGRAM_BROWSER'
        let g = version //版本号
        let f = randomTime
        return [j, g, f, naclUtil.encodeBase64(res)].join(":")
    })
    return ps
}

async function login(username, password) {
    let response, data;

    response = await fetch("https://www.instagram.com/accounts/login/?next=https%3A%2F%2Fwww.instagram.com%2Fajax%2Fbulk-route-definitions%2F&is_from_rle&__req=n", {
        "headers": {
            "accept": "*/*",
            "accept-language": "zh-CN,zh;q=0.9,en;q=0.8",
            "cache-control": "no-cache",
            "pragma": "no-cache",
            "priority": "u=1, i",
            "sec-ch-prefers-color-scheme": "light",
            "sec-ch-ua": "\"Google Chrome\";v=\"135\", \"Not-A.Brand\";v=\"8\", \"Chromium\";v=\"135\"",
            "sec-ch-ua-full-version-list": "\"Google Chrome\";v=\"135.0.7049.85\", \"Not-A.Brand\";v=\"8.0.0.0\", \"Chromium\";v=\"135.0.7049.85\"",
            "sec-ch-ua-mobile": "?0",
            "sec-ch-ua-model": "\"\"",
            "sec-ch-ua-platform": "\"Windows\"",
            "sec-ch-ua-platform-version": "\"15.0.0\"",
            "sec-fetch-dest": "empty",
            "sec-fetch-mode": "cors",
            "sec-fetch-site": "same-origin",
            "x-asbd-id": "359341",
            "x-fb-lsd": "AVqqjlWwnGU",
            "x-ig-d": "www",
            // "cookie": "csrftoken=upGQoQKe4JNavVM2SJ6I1Y; mid=Z_z8pwALAAGoFbVJ9ezU7eCPfCnj; ig_did=C1EC801F-FF73-4903-8A42-04F39FA0488F; ig_nrcb=1; datr=1fz8Zzis5nHdEF_12MRNn2Me; ps_l=1; ps_n=1; wd=1920x240",
            "Referer": "https://www.instagram.com/",
            "Referrer-Policy": "strict-origin-when-cross-origin"
        },
        "body": null,
        "method": "GET"
    })
    data = await response.text()

    const dom = new JSDOM(data);
    const scripts = dom.window.document.querySelectorAll("script")
    let key_id, public_key, version, csrf_token;

    scripts.forEach(element => {
        const len = element.dataset[`contentLen`]
        if (parseInt(len) > 90000) {
            let { require: [[, , , [{ __bbox: { define, instances, require } }]]] } = JSON.parse(element.innerHTML)
            define.forEach((v, i) => {
                if (v[0] === "InstagramSecurityConfig") {
                    [, , { csrf_token }] = v

                }
                if (v[0] === "InstagramPasswordEncryption") {
                    [, , { key_id, public_key, version }] = v
                }
            })
        }
    });


    console.log(key_id, public_key, version, csrf_token);

    let enc_password = await encPassword(password, key_id, public_key, version)

    const body = {
        enc_password: enc_password,
        caaF2DebugGroup: 0,
        isPrivacyPortalReq: false,
        loginAttemptSubmissionCount: 0,
        optIntoOneTap: false,
        queryParams: "{}",
        trustedDeviceRecords: "{}",
        username: username,
        jazoest: 21803,
    }

    const bodyString = querystring.stringify(body);

    response = await fetch("https://www.instagram.com/api/v1/web/accounts/login/ajax/", {
        "headers": {
            "accept": "*/*",
            "accept-language": "zh-CN,zh;q=0.9,en;q=0.8",
            "cache-control": "no-cache",
            "content-type": "application/x-www-form-urlencoded",
            "pragma": "no-cache",
            "priority": "u=1, i",
            "sec-ch-prefers-color-scheme": "light",
            "sec-ch-ua": "\"Google Chrome\";v=\"135\", \"Not-A.Brand\";v=\"8\", \"Chromium\";v=\"135\"",
            "sec-ch-ua-full-version-list": "\"Google Chrome\";v=\"135.0.7049.85\", \"Not-A.Brand\";v=\"8.0.0.0\", \"Chromium\";v=\"135.0.7049.85\"",
            "sec-ch-ua-mobile": "?0",
            "sec-ch-ua-model": "\"\"",
            "sec-ch-ua-platform": "\"Windows\"",
            "sec-ch-ua-platform-version": "\"15.0.0\"",
            "sec-fetch-dest": "empty",
            "sec-fetch-mode": "cors",
            "sec-fetch-site": "same-origin",
            "x-asbd-id": "359341",
            "x-csrftoken": csrf_token,
            "x-ig-app-id": "936619743392459",
            "x-ig-www-claim": "0",
            "x-instagram-ajax": "1021878646",
            "x-requested-with": "XMLHttpRequest",
            "x-web-session-id": "oqqw5t:fg2qc5:54i8mu"
        },
        "referrer": "https://www.instagram.com/",
        "referrerPolicy": "strict-origin-when-cross-origin",
        "body": bodyString,
        "method": "POST",
        "mode": "cors",
        "credentials": "include"
    });
    console.log(response);
    data = await response.text()
    console.log(data);

}
login("svip434940@gmail.com", "xh77.77ka")
